package com.showapi.app.util

import java.util.concurrent.ExecutorService
import java.util.concurrent.Future

class CommonUtil {

    //need_clearHtml是否对每个字段做html清理
    //need_trim 是否对每个字段trim
/*******	对整个list进行匹配，匹配结果为result
 def str="""
 <ul>
 <li class="li1"><a href="/Content/2015/12-25/1026362973.html">管理心理学（第2版）</a></li>
 <li><b>学科分类</b><i>管理学</i></li>
 </ul>
 """
 def list=[]
 list<<[b:'href=".*?>',e:'<',name:"aaa"]
 list<<[b:'学科分类</b><i>',e:'<',name:'bbb']
 makeSingleMat(str,list)
 list.each{println it}上述得到的是
 [b:href=".*?>, e:<, name:aaa, result:管理心理学（第2版）]
 [b:学科分类</b><i>, e:<, name:bbb, result:管理学]
 */
    def static fillSingleMat = { str, paraList, item = [:], need_clearHtml = false, need_trim = false ->
        def newstr = str
        paraList.each { n ->
            def mat_str = "(?is)${n.b}(.*?)${n.e}"
            def result  //一行配置对应一个result
            def rep_str = newstr.find(mat_str) {
                result = it[1]
                if (need_clearHtml) result = clearHtml(result)
                if (need_trim) result = result?.trim()
//				println newstr+"   "+ " get match:"+result
                if (n.name) {
                    item.put(n.name, result)
                }
                return it[0]//0是匹配到的整串
            }
            if (!rep_str) return
            int ind = newstr.indexOf(rep_str) + rep_str.size()
            newstr = newstr.substring(ind)
        }
        return item
    }

    def static fillSingleMat_test={

        def str="""
         <ul>
         <li class="li1"><a href="/Content/2015/12-25/1026362973.html">管理心理学（第2版）</a></li>
         <li><b>学科分类</b><i>管理学</i></li>
         </ul>
        """
        def list=[]
        list<<[b:'href=".*?>',e:'<',name:"aaa"]
        list<<[b:'学科分类</b><i>',e:'<',name:'bbb']
        fillSingleMat(str,list)
        list.each{println it}
        //将得到以下内容
//        [b:href=".*?>, e:<, name:aaa, result:管理心理学（第2版）]
//                [b:学科分类</b><i>, e:<, name:bbb, result:管理学]

    }


    //重试
    def static retryCallback={num,doClosure,judgeClosure=null->
        for(int i=0;i<num;i++){
            def succ=tryBoolean{
                def ret=doClosure()
                if(judgeClosure){
                    boolean good=judgeClosure(ret)
                    if(!good)Throw new Exception()
                }
            }
            if(succ)break
        }
    }
    //超时等待
    def static block_until_timeout={timeout,doClosure ->
        long now= System.currentTimeMillis()
        while(true){
            long diff= System.currentTimeMillis()-now
            if(diff<timeout){
                if(!doClosure()) Thread.sleep(1000)
                else break
            }else break

        }

    }
    def static getPage={
        return getNumWithDefault("page",1)
    }

    def  static getRetObj={ret_code=-1,remark=""->
        if(ret_code==null)ret_code=0
        if(remark)return [ret_code:ret_code,remark:remark]
        else return [ret_code:ret_code ]
    }
    //判断是否邮箱
    def static isEmail={email->
        def mat= email==~ /^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$/
        return mat
    }
    //取得传过来的数字，如果没传，使用默认值
    def static getNumWithDefault={params,name,defaultValue=0->
        def value=params.get(name)?.trim()
        if(value){
            if(NumberUtils.isDigits(value ))defaultValue=value.toInteger()
        }
        return defaultValue
    }
    //拷贝整个对象
    //alreadyCopiedObj=[:]//已经处理过的对象，不再处理
    def static copyMap(src,des,alreadyCopiedObj=[:]){
        src.each{k,v->
            des.put(k,v) //做浅拷贝
        }
        return des
    }
//
    //从params中拷贝参数
    def static copyParaValue={params,item,pList->
        pList.each{
            item."${it}"=params."${it}"?.trim()
        }
    }

    //拷贝对象属性
    def static copyProperty={src,propertyList,des->
        propertyList.each{
            def v=src.get(it)
            if(v)des.put(it,v)
        }
    }
//
    //从对象中移除属性
    def static removeProperty={obj,plist->
        if(!obj)return
        if(!plist)return
        plist.each{obj.remove(it)}
    }
//
    //把params中的某个key对应的所有值，添加到list中
    def static appendToList={list,obj->
        if(!list)list=[]
        if(!obj)return list
        if(obj instanceof String){
            list<<obj
        }else{
            obj.each{list<<it}
        }
        return list
    }
    //把params中的参数去空格
    def static trimParams(params){
        params?.each{k,v->
            if(v&&v instanceof String){
                params.put(k,v.trim())
            }
        }
        return params
    }


    def static tryBoolean(Closure clo){
        boolean succ = true;
        try {
            clo.call();
        } catch (Exception e) {
            e.printStackTrace();
            succ = false;
        }
        return succ;

    }

    //清除xss攻击
    def static clearXss={params->
        params.each{k,v->
            if(v instanceof String){
                v=v.replaceAll("<","")
                v=v.replaceAll(">","")
                params."${k}"=v
            }
        }
    }

    //清除html标签
    def static clearHtml={html->
        if(!html)return ""
        html=html.replaceAll(/<[^>]+>/,"")
        return html
    }

    //转义
    def static _htmlUnescape={str->
        if(!str)return ""
        str=StringUtils.replace(str, "\\x26", "&")
        return HtmlUtils.htmlUnescape(str)
    }
//
//     //执行超时线程，单位毫秒
    def static executeThreadWithTimeout={timeout,closure->
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Boolean result = false;
        Future<Boolean> future = executor.submit(closure);// 将任务提交到线程池中
        try {
            result = future.get(timeout, TimeUnit.MILLISECONDS);// 设定在几秒的时间内完成
        } catch ( Exception e) {
            log.info e.toString()
            future.cancel(true);// 中断执行此任务的线程
            throw e
        } finally{
            log.info ("线程服务关闭。");
            executor.shutdown();
        }
        return result

    }
//
    def static subGrouplist={list,int groupNum=1->
        int size=list.size()
        if(size==0)return []
        int mod=size/groupNum
        int left=size%groupNum
        if(left>0){mod++}

        def retList=[]
        (0..mod-1).each{
            int start= it*groupNum
            int end=(it+1)*groupNum
            if(end>size)end=size
            def sublist=list.subList(start,end)
            retList<<sublist
        }
        return retList
    }
}
